home *** CD-ROM | disk | FTP | other *** search
- /* $Id: ckmtio.c,v 1.9 91/12/27 21:48:25 fdc Exp $
- * $Source: /uw/mackermit/RCS/ckmtio.c,v $
- *------------------------------------------------------------------
- * $Log: ckmtio.c,v $
- * Revision 1.9 91/12/27 21:48:25 fdc
- * Change fatal to macfatal, make all lines 80 chars or less.
- *
- * Revision 1.8 91/12/15 23:17:55 rick
- * ut9
- *
- * Revision 1.7 91/10/13 13:43:39 rick
- * UT(7)
- *
- * Revision 1.6 91/10/01 12:17:06 rick
- * UT(5)
- *
- * Revision 1.5 91/09/25 12:17:37 rick
- * Command window in TE. Multiple vt100 windows for command window.
- *
- * Revision 1.4 91/09/12 21:50:54 rick
- * UT(3). Install on watsun
- *
- * Revision 1.3 1991/09/12 16:43:03 rick
- * Cleanups.
- *
- * Revision 1.2 1991/09/10 22:21:49 rick
- * Update to UTexas(2)
- *
- * Revision 1.1 1991/09/10 19:18:06 rick
- * Initial revision
- *
- *------------------------------------------------------------------
- * $Endlog$
- */
-
- /* edit 3/25/87 by Paul Placeway -- don't let the TextEdit buffer get too */
- /* big, because the Mac will crash if it does */
- /* Version 0.8(35) - Jim Noble at Planning Research Corporation, June 1987. */
- /* Ported to Megamax native Macintosh C compiler. */
-
- /* C K M T I O -- interrupt, console, and port functions for Mac Kermit */
-
- /*
- Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
- York. Permission is granted to any individual or institution to use this
- software as long as it is not sold for profit. This copyright notice must be
- retained. This software may not be included in commercial products without
- written permission of Columbia University.
- */
-
- /*
- Variables:
-
- dftty -- Pointer to default tty name string, like "/dev/tty".
- dfloc -- 0 if dftty is console, 1 if external line.
- dfprty -- Default parity
- dfflow -- Default flow control
- ckxech -- Flag for who echoes console typein:
- 1 - The program (system echo is turned off)
- 0 - The system (or front end, or terminal).
- functions that want to do their own echoing should check this flag
- before doing so.
-
- Functions for assigned communication line (either external or console tty):
-
- ttopen(ttname,local,mdmtyp,timo) -- Open the named tty for exclusive access.
- ttclos() -- Close & reset the tty, releasing any access lock.
- ttpkt(speed,flow) -- Put the tty in packet mode and set the speed.
- ttvt(speed,flow) -- Put the tty in virtual terminal mode.
- ttinl(dest,max,timo) -- Timed read line from the tty.
- ttinc(timo) -- Timed read character from tty.
- ttchk() -- See how many characters in tty input buffer.
- ttxin(n,buf) -- Read n characters from tty (untimed).
- ttol(string,length) -- Write a string to the tty.
- ttoc(c) -- Write a character to the tty.
- ttflui() -- Flush tty input buffer.
-
- Functions for console terminal:
-
- congm() -- Get console terminal modes.
- concb() -- Put the console in single-character wakeup mode with no echo.
- conbin() -- Put the console in binary (raw) mode.
- conres() -- Restore the console to mode obtained by congm().
- conoc(c) -- Unbuffered output, one character to console.
- conol(s) -- Unbuffered output, null-terminated string to the console.
- conxo(n,s) -- Unbuffered output, n characters to the console.
- conchk() -- Check if characters available at console.
- coninc() -- Get a character from the console.
- conint() -- Enable terminal interrupts on the console.
- connoi() -- Disable terminal interrupts on the console.
-
- Time functions
-
- msleep(m) -- Millisecond sleep
- ztime(&s) -- Return pointer to date/time string
- */
-
- #include <StdArg.h>
-
- #include "ckcdeb.h" /* Formats for debug() */
- #include "ckcker.h" /* kermit defs */
- #include "ckmdef.h" /* macintosh defs */
- #include "ckcasc.h"
- #include "ckmwin.h"
- #include "ckmcon.h"
- #include "ckmptp.h" /* ckm* Prototypes */
-
- char *dftty = "Modem";
-
- /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
-
- int dfloc = 1;
-
- /* Other defaults */
-
- int dfprty = 0; /* Default parity */
- int ttprty = 0; /* Parity in use. */
- long ttspeed = -1; /* For saving speed */
- int dfflow = 1; /* Xon/Xoff flow control */
- int ttflow = -9; /* For saving flow */
- int fDTR = 0; /* DTR input flow control */
- int fCTS = 0; /* CTS output flow control */
- int fInX = 0; /* send xoff when buffer almost full */
-
- int backgrd = 0; /* a Mac is allways in foreground */
-
- /* Local variables */
-
- int drop_dtr = 0; /* drop DTR on Quit */
-
- /* buffer and pointer for input processing */
- static char *my_input_buf; /* we give this to the serial driver queue */
-
- /* Private buffer for myread() and its companions. Not for use by anything
- * else. ttflui() is allowed to reset them to initial values. ttchk() is
- * allowed to read my_count.
- *
- * my_item is an index into mybuf[]. Increment it *before* reading mybuf[].
- *
- * A global parity mask variable could be useful too. We could use it to
- * let myread() strip the parity on its own, instead of stripping sign
- * bits as it does now.
- */
-
- /* #define MYBUFLEN 256 */
- #define MYBUFLEN 2048
- static unsigned char *mybufp; /* Buffer, including push back */
- static int my_count = 0; /* Number of chars still in mybuf */
- static int my_item = -1; /* Last index read from mybuf[] */
-
-
- #ifdef COMMENT
- #define TTBUFL 200 /* good size (it's RBUFL guys!) */
- static unsigned char *ttbuf;
- #endif
-
- static char *tto_buf; /* output buffer for ttol() */
- static ParamBlockRec iopb; /* paramater block for ttol() */
- static long tto_startticks; /* when we started the output */
- #define XOFFTIMEO 480L /* a timeout of 8 seconds (in ticks) */
-
- short dfltVol; /* The volume to be used for Take- and Log-File */
-
- /* true if using RAM serial driver (usually TRUE) */
- extern Boolean usingRAMdriver,
- have_128roms; /* true if we are a Plus or better */
- extern char ttname[];
-
- #define SIGTYP long
- extern SIGTYP (*alarmfunc)();
- extern SIGTYP (*intfunc)();
- typedef unsigned long ulong;
- extern ulong alarmtime = 0; /* global alarm time */
-
- /****************************************************************************/
- /* S Y S I N I T -- System-dependent program initialization. */
- /****************************************************************************/
- sysinit ()
- {
- ParamBlockRec pb;
-
- mac_init (); /* Set up the Mac */
-
- /* get the default volume reference number for Take- and Log-Files */
- pb.volumeParam.ioNamePtr = NIL;
- PBGetVol (&pb, FALSE);
- dfltVol = pb.volumeParam.ioVRefNum;
-
- findfinderfiles (); /* see if file was selected */
-
- mac_post_load_init (); /* show the terminal window and stuff */
-
- return (0);
- } /* sysinit */
-
- /* init terminal I/O buffers */
- inittiobufs()
- {
- #ifdef COMMENT
- if ((ttbuf = (unsigned char *) NewPtr(TTBUFL + 1)) == NIL)
- macfatal("Can't allocate ttbuf", 0);
- #endif
- if ((mybufp = (unsigned char *) NewPtr(MYBUFLEN + 4)) == NIL)
- macfatal("Can't allocate mybufp", 0);
- my_count = 0; /* Number of chars still in mybuf */
- my_item = -1; /* Last index read from mybuf[] */
-
- if ((tto_buf = (char *) NewPtr(MAXSP)) == NIL)
- macfatal("Can't allocate tto_buf", 0);
- if ((my_input_buf = (char *) NewPtr(MYBUFSIZE)) == NIL)
- macfatal("Can't allocate my_input_buf", 0);
- }
-
- /****************************************************************************/
- /* P O R T _ O P E N -- Open and init a serial port. port is either -6 (for */
- /* the modem port) or -8 (for the printer port) */
- /****************************************************************************/
-
- #define RamSDOpen RAMSDOPEN /* fix routine name */
-
- port_open (int port)
- {
- int err;
-
- if ((port != -6) && (port != -8))
- port = -6;
-
- try_again:
- /* Set up IO drivers */
- innum = port;
- outnum = port - 1;
- if (innum == -6) {
- if (((err = OpenDriver ("\p.AIn", &innum)) != noErr) ||
- ((err = OpenDriver ("\p.AOut", &outnum)) != noErr))
- macfatal ("Could not open the Modem port: ", err);
- } else {
- if (((err = OpenDriver ("\p.BIn", &innum)) != noErr) ||
- ((err = OpenDriver ("\p.BOut", &outnum)) != noErr)) {
- printerr("Could not open the Printer port. Try\
- turning off Appletalk.", 0);
- port = -6;
- goto try_again;
- }
- }
-
- /* try for the RAM driver */
- if (innum == -6)
- err = RamSDOpen (sPortA);
- else
- err = RamSDOpen (sPortB);
-
- if (err == noErr) {
- usingRAMdriver = TRUE;
- } else {
- usingRAMdriver = FALSE;
- printerr("Can't open RAM serial driver; using the ROM driver\
- (without flow control).",0);
- }
-
- err = SerSetBuf (innum, my_input_buf, MYBUFSIZE);
- /* Make driver use larger buff */
- if (err)
- printerr ("Trouble making IO buffer:", err);
-
- switch (port) {
- case -6:
- strcpy(ttname, "Modem");
- break;
- case -8:
- strcpy(ttname, "Printer");
- break;
- }
- }
-
- /*****************************************************************************/
- /* P O R T _ C L O S E -- Close down the serial port. */
- /*****************************************************************************/
-
- #define RamSDClose RAMSDCLOSE
-
- port_close()
- {
- int err;
- ParamBlockRec cpb;
-
- err = KillIO(innum); /* Kill off IO drivers */
- if (err != noErr)
- printerr("trouble KillIO-ing serial input driver:",err);
- err = KillIO(outnum); /* Kill off IO drivers */
- if (err != noErr)
- printerr("trouble KillIO-ing serial output driver:",err);
-
- err = SerSetBuf (innum, NULL, 0); /* Make driver default buffer */
- if (err != noErr)
- printerr("trouble resetting serial IO buffer:",err);
-
- if (usingRAMdriver) {
- if (!drop_dtr) {
- bzero((char *) &cpb, sizeof(cpb));
- cpb.cntrlParam.ioNamePtr = NULL; /* IM-IV p226 */
- /* tell the ram driver not to lower DTR on close */
- cpb.cntrlParam.csCode = 16; /* misc serial control */
- *((unsigned char *) cpb.cntrlParam.csParam) = 0x80;
- /* don't lower DTR */
- cpb.cntrlParam.ioCRefNum = innum;
- err = PBControl(&cpb, FALSE);
- if ((err != noErr) && (err != -1))
- printerr(
- "trouble telling RAM serial driver (in) not to lower DTR:",
- err);
-
- bzero((char *) &cpb, sizeof(cpb));
- cpb.cntrlParam.ioNamePtr = NULL; /* IM-IV p226 */
- cpb.cntrlParam.csCode = 16; /* misc serial control */
- /* don't lower DTR */
- *((unsigned char *) cpb.cntrlParam.csParam) = 0x80;
- cpb.cntrlParam.ioCRefNum = outnum;
- err = PBControl(&cpb, FALSE);
- if ((err != noErr) && (err != -1))
- printerr("\
- trouble telling RAM serial driver (out) not to lower DTR:",err);
- }
-
- RamSDClose (sPortA); /* this "returns" void */
- }
-
- err = CloseDriver (innum);
- if (err != noErr)
- printerr("trouble closing serial input driver:",err);
- /*
- * For some reason or other, doing this close on a 64k ROM machine will cause
- * the mouse to freeze. Since the input driver is the only one that really
- * matters, we just close it.
- */
- if (have_128roms) {
- err = CloseDriver (outnum);
- if (err != noErr)
- printerr("trouble closing serial output driver:",err);
- }
- }
-
- /****************************************************************************/
- /* T T O P E N -- Open a tty for exclusive access. */
- /* Returns 0 on success, -1 on failure. */
- /****************************************************************************/
- ttopen (ttname, lcl, modem, timeo)
- char *ttname;
- int *lcl;
- int modem;
- int timeo;
- {
- int port, *aport;
- char tmp[100];
-
- my_count = 0; /* Initialize myread() stuff */
- my_item = -1;
-
- if (*lcl < 0)
- *lcl = 1; /* always in local mode */
-
- #ifdef COMMENT
- if (ttbuf == NIL)
- macfatal("No ttbuf", 0);
- #endif
- if (mybufp == NIL)
- macfatal("No mybufp", 0);
- if (tto_buf == NIL)
- macfatal("No tto_buf", 0);
- if (my_input_buf == NIL)
- macfatal("No my_input_buf", 0);
-
- iopb.ioParam.ioResult = 0; /* no pending output */
-
- iopb.ioParam.ioActCount = 0; /* for error checking in ttol() */
- iopb.ioParam.ioReqCount = 0;
-
- /*
- * Re-open the port if it has changed.
- */
- strcpy(tmp, ttname);
- lower(tmp);
- if (strcmp(tmp, "printer") == 0)
- port = -8;
- else if (strcmp(tmp, "modem") == 0)
- port = -6;
- else {
- printfalert("Unknown port %s, using Modem", ttname);
- port = -6;
- }
- aport = &port;
- if (port != innum) { /* if port changed */
- port_close();
- port_open(port);
- if (!setserial (innum, outnum, speed, KPARITY_NONE))
- printfalert("Problem setting port speed");
- (void) sershake(flow);
- }
-
- return (0);
- } /* ttopen */
-
-
-
- /****************************************************************************/
- /* T T C L O S -- Close the TTY, releasing any lock. */
- /****************************************************************************/
- ttclos ()
- {
- my_count = 0; /* Initialize myread() stuff */
- my_item = -1;
-
- return;
- } /* ttclos */
-
- /*
- * sershake
- * Set handshake parameters on serial port.
- */
- int sershake (int flow)
- {
- int err;
- ParamBlockRec pb;
- SerShk *controlparam; /* To change serial driver paramaters */
-
- bzero((char *)&pb, sizeof(pb));
- controlparam = (SerShk *) &pb.cntrlParam.csParam;
- /*
- * Old code used to issue controls to in and out sides. IM-IV
- * says to use the output driver.
- */
- pb.cntrlParam.ioCRefNum = outnum;
- if (have_128roms)
- pb.cntrlParam.csCode = 14; /* SerHShake + DTR */
- else
- pb.cntrlParam.csCode = 10; /* SerHShake */
-
- if (flow)
- controlparam->fXOn = TRUE; /* obey flow control */
- else
- controlparam->fXOn = FALSE; /* ignore flow control */
- controlparam->fCTS = fCTS; /* output flow control */
- controlparam->xOn = 17;
- controlparam->xOff = 19;
- controlparam->errs = FALSE;
- controlparam->evts = FALSE;
- if (flow && usingRAMdriver && fInX) /* old ROM driver can't do this */
- controlparam->fInX = TRUE; /* send flow control when almost full */
- else
- controlparam->fInX = FALSE;
- controlparam->fDTR = fDTR; /* input flow control */
-
- err = PBControl(&pb, FALSE);
- if (err != noErr) {
- printfalert("sershake: problem setting handshake: %d", err);
- return -1;
- }
-
- return 0;
- }
-
-
-
- /****************************************************************************/
- /* T T P K T -- Condition the communication line for packets. */
- /* If called with speed > -1, also set the speed. */
- /* Returns 0 on success, -1 on failure. */
- /****************************************************************************/
- ttpkt (spd, flow, parity) /* we only care about flow here */
- int spd;
- int flow;
- int parity;
- {
- ttprty = parity; /* Let other tt functions see these. */
- ttspeed = speed;
- ttflow = flow; /* Now make this available too. */
-
- fInX = TRUE;
- return(sershake(flow));
- }
-
-
- /****************************************************************************/
- /* T T V T -- Condition the communication line for a virtual terminal. */
- /* If called with spd > -1, also set the spd. */
- /* Returns 0 on success, -1 on failure. */
- /****************************************************************************/
- ttvt (spd, flow, parity) /* all ignoreed */
- int spd;
- int flow;
- int parity;
- {
- (void) ttres();
- return (0);
- } /* ttvt */
-
-
- /****************************************************************************/
- /* T T F L U I -- Flush tty input buffer */
- /****************************************************************************/
- ttflui ()
- {
- int err;
-
- my_count = 0; /* Initialize myread() stuff */
- my_item = -1;
-
- err = KillIO (innum);
- if (err)
- printerr ("Bad input clear", err);
-
- return (0);
- } /* ttflui */
-
- ttfluo() { /* Flush output buffer */
- return(0); /* (dummy for now) */
- }
-
- /****************************************************************************/
- /* T T S N D B -- Send a break */
- /****************************************************************************/
- ttsndb() {
- long finalticks;
-
- /* delay wants 1/60th units */
-
- SerSetBrk (outnum); /* start breaking */
- Delay ((long) 15, &finalticks); /* delay about 250ms */
- SerClrBrk (outnum); /* stop breaking */
- }
-
- /****************************************************************************/
- /*
- * Flushio:
- * Initialize some communications constants, and clear screen and
- * character buffers. */
- /****************************************************************************/
- flushio ()
- {
- int err;
-
- err = KillIO (innum);
- if (err)
- printerr ("Bad input clear", err);
- err = KillIO (outnum);
- if (err)
- printerr ("Bad ouput clear", err);
- } /* flushio */
-
-
-
- /****************************************************************************/
- /* sendbreak - sends a break across the communictions line.
- *
- * The argument is in units of approximately 0.05 seconds (or 50
- * milliseconds). To send a break of duration 250 milliseconds the
- * argument would be 5; a break of duration 3.5 seconds would be (umm,
- * lets see now) 70.
- *
- */
- /****************************************************************************/
- sendbreak (msunit)
- int msunit;
- {
- long finalticks;
-
- /* delay wants 1/60th units. We have 3/60 (50 ms.) units, convert */
-
- msunit = msunit * 3;
-
- SerSetBrk (outnum); /* start breaking */
- Delay ((long) msunit, &finalticks); /* delay */
- SerClrBrk (outnum); /* stop breaking */
- } /* sendbreak */
-
- /****************************************************************************/
- /* toggledtr - Turn DTR off, wait a bit, turn it back on.
- *
- * the argument is in the same units as sendbreak (see above).
- */
- /****************************************************************************/
- toggle_dtr (msunit)
- int msunit;
- {
- long finalticks;
- ParamBlockRec pb;
- int err;
-
- if (usingRAMdriver) {
- /* delay wants 1/60th units. We have 3/60 (50 ms.) units, convert */
-
- msunit = msunit * 3;
-
- pb.cntrlParam.csCode = 18; /* lower DTR */
- pb.cntrlParam.ioCRefNum = outnum;
- err = PBControl (&pb, FALSE);
- if (err != noErr)
- printerr ("toggle_dtr() trouble lowering DTR: ", err);
-
- Delay ((long) msunit, &finalticks); /* delay */
-
- pb.cntrlParam.csCode = 17; /* raise DTR */
- pb.cntrlParam.ioCRefNum = outnum;
- err = PBControl (&pb, FALSE);
- if (err != noErr)
- printerr ("toggle_dtr() trouble raising DTR: ", err);
- }
- } /* sendbreak */
-
- /****************************************************************************/
- /* do_xon - xon the output port and send an xon (control-Q) character */
- /****************************************************************************/
- do_xon ()
- {
- ParamBlockRec pb;
- int err;
-
- if (usingRAMdriver) {
- pb.cntrlParam.csCode = 22; /* clear XOFF for my output */
- pb.cntrlParam.ioCRefNum = outnum;
- err = PBControl (&pb, FALSE);
- if (err != noErr)
- printerr ("do_xon() trouble unblocking output port: ", err);
-
- pb.cntrlParam.csCode = 24; /* unconditionally send XON */
- pb.cntrlParam.ioCRefNum = outnum;
- err = PBControl (&pb, FALSE);
- if (err != noErr)
- printerr ("do_xon() trouble sending XON: ", err);
- } else {
- OutputChar (ttermw, '\021'); /* XON */
- }
- } /* sendbreak */
-
- /****************************************************************************/
- /* T T S S P D -- Set tty speed */
- /****************************************************************************/
-
- ttsspd (cps) int cps; {
- if (setserial (innum, outnum, cps*10, KPARITY_NONE))
- return(0);
- else
- return (-1);
- }
-
-
- /****************************************************************************/
- /* T T G S P D -- Set tty speed */
- /****************************************************************************/
-
- long
- ttgspd () {
- if (speed <= 0L)
- printerr("Speed got reset, now == ", (int) speed);
- return (speed);
- }
-
-
- /* Interrupt Functions */
-
- /****************************************************************************/
- /* Set up terminal interrupts on console terminal */
- /* Set an interrupt trap. */
- /****************************************************************************/
- VOID conint(SIGTYP (*f)(int), SIGTYP (*s)(int))
- {
- return;
- } /* conint */
-
-
-
- /****************************************************************************/
- /* Reset console terminal interrupts */
- /****************************************************************************/
- VOID connoi ()
- {
- return;
- } /* connoi */
-
- /****************************************************************************/
- /* writeps - write a pascal string to the serial port.
- *
- */
- /****************************************************************************/
- writeps (s)
- char *s;
- {
- long wcnt, w2;
- char *s2;
-
- w2 = wcnt = *s++; /* get count */
-
- for (s2 = s; w2 > 0; w2--, s2++) /* add parity */
- *s2 = dopar (*s2);
-
- (void) ttol(s, wcnt); /* ttol will printerr() if it has a problem */
-
- return;
- } /* writeps */
-
- extern Boolean have_multifinder;/* true if running under MF */
- extern Boolean in_background; /* becomes true if running MF and in bg */
- extern long mf_sleep_time; /* number of 60ths between task time */
-
- /****************************************************************************/
- /* T T O L -- Similar to "ttinl", but for writing. */
- /****************************************************************************/
- ttol (s, n)
- char *s;
- int n;
- {
- long finalticks;
- int err;
- ParamBlockRec cpb;
-
- #ifdef COMMENT
- debug(F101,"ttol n","",n);
- debug(F101," s","",s);
-
- /*
- * the straight-forward way to write out a buffer: synchronously
- */
- finalticks = n;
- err = FSWrite(outnum, &finalticks, s);
- if ((err != noErr) || (finalticks != n)) {
- printerr("ttol FSWrite error: ", err);
- return (-1);
- }
- return (n);
- #endif
-
- /*
- * The fancy to write out strings: do async writes, waiting for the
- * previous call to finish first (and possibly unsticking the serial
- * driver)
- */
-
- /* wait for previous call to finish */
- /* while the prev. request is still running */
- while (iopb.ioParam.ioResult == 1) {
- /* if we're running protocol */
- if (have_multifinder && protocmd != 0) {
- miniparser (TRUE); /* keep mac running */
- finalticks = TickCount ();
- } else { /* else terminal emulation */
- Delay ((long) 1, &finalticks); /* wait for a bit */
- }
- /* (PWP) If we have waited too long, unblock the output (keep the
- Mac from freezing up) */
- if ((usingRAMdriver) && (finalticks > (tto_startticks + XOFFTIMEO))) {
- cpb.cntrlParam.csCode = 22; /* clear XOFF for my output */
- cpb.cntrlParam.ioCRefNum = outnum;
- err = PBControl (&cpb, FALSE);
- if (err != noErr)
- printerr ("ttol() trouble unblocking output port: ", err);
- tto_startticks = TickCount (); /* get starting time */
- }
- }
-
- /* check for errors in previous call */
- if (iopb.ioParam.ioResult) {
- printerr ("Error in previous PBWrite:", iopb.ioParam.ioResult);
- return (-1);
- }
- if (iopb.ioParam.ioActCount != iopb.ioParam.ioReqCount) {
- printerr ("PBWrite to serial didn't write enough: ",
- iopb.ioParam.ioActCount);
- printerr ("(asked for:)", iopb.ioParam.ioReqCount);
- return (-1);
- }
-
- /* the previous call is now done, so we can load in our new information */
-
- if (n > MAXSP) { /* MAXSP == sizeof(tto_buf) */
- printerr("ttol asked to write too many chars: ", n);
- return (-1);
- }
- bcopy(s, tto_buf, n); /* in ckmfio.h if nowhere else */
-
- iopb.ioParam.ioCompletion = NULL;
- iopb.ioParam.ioNamePtr = NULL;
- iopb.ioParam.ioVRefNum = 0;
-
- iopb.ioParam.ioRefNum = outnum;
- iopb.ioParam.ioVersNum = 0;
- iopb.ioParam.ioPermssn = 0;
- iopb.ioParam.ioMisc = NULL;
- iopb.ioParam.ioBuffer = tto_buf;
- iopb.ioParam.ioReqCount = (long) n;
- iopb.ioParam.ioPosMode = 0;
- iopb.ioParam.ioPosOffset = 0;
-
- tto_startticks = TickCount (); /* get starting time */
-
- PBWrite (&iopb, TRUE); /* request an async. write */
- if (protocmd != 0)
- miniparser (TRUE); /* allow other tasks to run */
- return (n); /* fake a good run */
- } /* ttol */
-
-
- /* T T O C -- Output a character to the communication line */
-
- /*
- This function should only used for interactive, character-mode operations,
- like terminal connection, script execution, dialer i/o, where the overhead
- of the signals and alarms does not create a bottleneck.
- */
-
- ttoc(c) char c; {
- char foo[2];
-
- foo[0] = c;
- foo[1] = '\0';
- return (ttol(foo, 1));
- }
-
- /* ckumyr.c by Kristoffer Eriksson, ske@pkmab.se, 15 Mar 1990. */
-
-
- /* myread() -- Efficient read of one character from communications line.
- *
- * Uses a private buffer to minimize the number of expensive read() system
- * calls. Essentially performs the equivalent of read() of 1 character, which
- * is then returned. By reading all available input from the system buffers
- * to the private buffer in one chunk, and then working from this buffer, the
- * number of system calls is reduced in any case where more than one character
- * arrives during the processing of the previous chunk, for instance high
- * baud rates or network type connections where input arrives in packets.
- * If the time needed for a read() system call approaches the time for more
- * than one character to arrive, then this mechanism automatically compensates
- * for that by performing bigger read()s less frequently. If the system load
- * is high, the same mechanism compensates for that too.
- *
- * myread() is a macro that returns the next character from the buffer. If the
- * buffer is empty, mygetbuf() is called. See mygetbuf() for possible error
- * returns.
- *
- * This should be efficient enough for any one-character-at-a-time loops.
- * For even better efficiency you might use memcpy()/bcopy() or such between
- * buffers (since they are often better optimized for copying), but it may not
- * be worth it if you have to take an extra pass over the buffer to strip
- * parity and check for CTRL-C anyway.
- *
- * Note that if you have been using myread() from another program module, you
- * may have some trouble accessing this macro version and the private variables
- * it uses. In that case, just add a function in this module, that invokes the
- * macro.
- */
-
- #define mac_myread(timeo_ticks,intim) (--my_count < 0 \
- ? mac_mygetbuf(timeo_ticks,intim) \
- : (int) (mybufp[++my_item]))
-
- /* Specification: Push back up to one character onto myread()'s queue.
- *
- * This implementation: Push back characters into mybuf. At least one character
- * must have been read through myread() before myunrd() may be used. After
- * EOF or read error, again, myunrd() can not be used. Sometimes more than
- * one character can be pushed back, but only one character is guaranteed.
- * Since a previous myread() must have read its character out of mybuf[],
- * that guarantees that there is space for at least one character. If push
- * back was really needed after EOF, a small addition could provide that.
- *
- * myunrd() is currently not called from anywhere inside kermit...
- */
- #ifdef NOTUSED
- myunrd(ch) CHAR ch; {
- if (my_item >= 0) {
- mybufp[my_item--] = ch;
- ++my_count;
- }
- }
- #endif
-
- /* mygetbuf() -- Fill buffer for myread() and return first character.
- *
- * This function is what myread() uses when it can't get the next character
- * directly from its buffer. First, it calls a system dependent myfillbuf()
- * to read at least one new character into the buffer, and then it returns
- * the first character just as myread() would have done. This function also
- * is responsible for all error conditions that myread() can indicate.
- *
- * Returns: When OK => a positive character, 0 or greater.
- * When EOF => -2.
- * When error => -3, error code in errno.
- *
- * Older myread()s additionally returned -1 to indicate that there was nothing
- * to read, upon which the caller would call myread() again until it got
- * something. The new myread()/mygetbuf() always gets something. If it
- * doesn't, then make it do so! Any program that actually depends on the old
- * behaviour will break.
- *
- * The older version also used to return -2 both for EOF and other errors,
- * and used to set errno to 9999 on EOF. The errno stuff is gone, EOF and
- * other errors now return different results, although Kermit currently never
- * checks to see which it was. It just disconnects in both cases.
- *
- * Kermit lets the user use the quit key to perform some special commands
- * during file transfer. This causes read(), and thus also mygetbuf(), to
- * finish without reading anything and return the EINTR error. This should
- * be checked by the caller. Mygetbuf() could retry the read() on EINTR,
- * but if there is nothing to read, this could delay Kermit's reaction to
- * the command, and make Kermit appear unresponsive.
- *
- * The debug() call should be removed for optimum performance.
- */
- /* myfillbuf():
- * System-dependent read() into mybuf[], as many characters as possible.
- *
- * Returns: OK => number of characters read, always more than zero.
- * EOF => 0
- * Error => -1, error code in errno.
- *
- * If there is input available in the system's buffers, all of it should be
- * read into mybuf[] and the function return immediately. If no input is
- * available, it should wait for a character to arrive, and return with that
- * one in mybuf[] as soon as possible. It may wait somewhat past the first
- * character, but be aware that any such delay lengthens the packet turnaround
- * time during kermit file transfers. Should never return with zero characters
- * unless EOF or irrecoverable read error.
- *
- * Correct functioning depends on the correct tty parameters being used.
- * Better control of current parameters is required than may have been the
- * case in older Kermit releases. For instance, O_NDELAY (or equivalent) can
- * no longer be sometimes off and sometimes on like it used to, unless a
- * special myfillbuf() is written to handle that. Otherwise the ordinary
- * myfillbuf()s may think they have come to EOF.
- *
- * If your system has a facility to directly perform the functioning of
- * myfillbuf(), then use it. If the system can tell you how many characters
- * are available in its buffers, then read that amount (but not less than 1).
- * If the system can return a special indication when you try to read without
- * anything to read, while allowing you to read all there is when there is
- * something, you may loop until there is something to read, but probably that
- * is not good for the system load.
- */
-
-
- mac_mygetbuf(long timeo_tics, long intim) {
- long avail; /* can't be register */
- long finaltics; /* can't be register */
- int err;
- extern int tlevel;
-
- if (mybufp == NIL)
- macfatal("No mybufp (in mac_mygetbuf())", 0);
-
- for (;;) {
- SerGetBuf (innum, &avail); /* Get available count */
-
- if (avail > 0)
- break; /* we can get these chars */
-
- /* no chars availiable yet */
- if ((protocmd != 0) || (tlevel > -1) || intfunc) {
- miniparser (TRUE); /* keep mac running */
- if (sstate == 'a') { /* abort occured? */
- if (intfunc) {
- sstate = '\0';
- (*intfunc)(0);
- } else
- return (-1); /* ugh, look like timeout */
- }
- }
-
- /*
- * Check alarm() timeouts.
- */
- if (alarmtime && alarmfunc && (((ulong)TickCount() - alarmtime) > 0))
- (*alarmfunc)(0);
-
- finaltics = TickCount ();
- if (timeo_tics > 0) { /* Want to do timeout? */
- if (intim + timeo_tics < finaltics) {
- return (-1); /* Too long, give up */
- }
- }
-
- /* go back and try to get more chars */
- }
-
- if (avail > MYBUFLEN)
- avail = MYBUFLEN;
-
- /*
- * CAREFUL: the Mac FSRead() function gets how much to read,
- * AND PUTS HOW MUCH IT DID READ into avail
- */
- err = FSRead (innum, &avail, mybufp); /* Into our buffer */
-
- if (err != noErr) {
- screen(SCR_EM,0,(long) err,"Serial input error:");
- return (-3); /* return input error */
- }
- if (avail <= 0) {
- screen(SCR_EM, 0, (long) avail,
- "No serial input error, but didn't read any:");
- return (-3); /* return input error */
- }
-
- /* not at end of packet yet, so let other tasks have a chance */
- if (in_background)
- miniparser (TRUE); /* allow other tasks to run */
-
- my_count = (int) avail;
-
- /* debug(F101, "myfillbuf read", "", my_count); */
-
- --my_count;
- return((int) (mybufp[my_item = 0]));
- }
-
-
-
-
- /****************************************************************************/
- /* T T I N L -- Read a record (up to break character) from comm line. */
- /*
- If no break character encountered within "max", return "max" characters,
- with disposition of any remaining characters undefined. Otherwise, return
- the characters that were read, including the break character, in "dest" and
- the number of characters read as the value of function, or 0 upon end of
- file, or -1 if an error occurred. Times out & returns error if not completed
- within "timo" seconds.
- */
- /*
- Reads up to "max" characters from the communication line, terminating on
- the packet-end character (eol), or timing out and returning -1 if the eol
- character not encountered within "timo" seconds. The characters that were
- input are copied into "dest" with their parity bits stripped if parity was
- selected. Returns the number of characters read. Characters after the
- eol are available upon the next call to this function.
-
- The idea is to minimize the number of system calls per packet, and also to
- minimize timeouts. This function is the inner loop of the program and must
- be as efficient as possible. The current strategy is to use myread().
-
- WARNING: this function calls parchk(), which is defined in another module.
- Normally, ckutio.c does not depend on code from any other module, but there
- is an exception in this case because all the other ck?tio.c modules also
- need to call parchk(), so it's better to have it defined in a common place.
- */
- /****************************************************************************/
-
- #define CTRLC '\03'
-
- #ifdef PARSENSE
- ttinl(dest,max,timo,eol,start) int max,timo; CHAR *dest, eol, start; {
- int flag;
- #else
- ttinl(dest,max,timo,eol) int max,timo; CHAR *dest, eol; {
- #endif
- register int i, m, n; /* local variables */
- int x, ccn;
- long timeoticks;
- long intim; /* when we started */
-
- debug(F101,"ttinl max","",max);
- debug(F101,"ttinl timo","",timo);
-
- #ifdef PARSENSE
- debug(F000,"ttinl start","",start);
- flag = 0; /* Start of packet flag */
- #endif
-
- ccn = 0; /* Control-C counter */
- x = 0; /* Return code */
- m = (ttprty) ? 0177 : 0377; /* Parity stripping mask. */
- *dest = '\0'; /* Clear destination buffer */
-
- if (timo <= 0) { /* untimed */
- timo = 0; /* Safety */
- intim = 0; /* tell mac_myread not to timeout */
- timeoticks = 0;
- } else {
- timeoticks = timo * 60;
- intim = TickCount (); /* now */
- }
-
- i = 0;
- while (i < max-1) {
- /* debug(F101,"ttinl i","",i); */
- if ((n = mac_myread(timeoticks,intim)) < 0) {
- debug(F101,"ttinl myread failure, n","",n);
- x = -1; break;
- }
- /* debug(F101,"ttinl char","",n&m); */
-
- #ifdef PARSENSE
- if ((flag == 0) && ((n & 0x7f) == start)) flag = 1;
- if (flag) dest[i++] = n & m;
- #else
- dest[i++] = n & m;
- #endif
- if ((n & 0x7f) == CTRLC) { /* Check for ^C^C */
- if (++ccn > 1) { /* If we got 2 in a row, bail out. */
- screen(SCR_EM,0,(long) 0,"Remote side ^C^C abort...");
- return(-2);
- }
- } else ccn = 0; /* Not ^C, so reset ^C counter, */
-
- #ifdef PARSENSE
- if (flag == 0) {
- debug(F101,"ttinl skipping","",n);
- continue;
- }
- #endif
-
- /* Check for end of packet */
-
- if ((n & 0x7f) == eol) {
- debug(F101,"ttinl got eol","",eol);
- dest[i] = '\0'; /* Yes, terminate the string, */
- /* debug(F101,"ttinl i","",i); */
-
- #ifdef PARSENSE
- /* Here's where we actually check and adjust the parity. */
- /* The major flaw here is if parity is NONE (ttprty = 0) and the packets */
- /* really do have no parity, then parchk() is called for every packet. */
- /* In practice, this doesn't really harm efficiency noticably, but it would */
- /* be better if ttinl() had a way of knowing to stop doing this once a */
- /* particular file transfer had been started and checked. */
- if (ttprty == 0) {
- if ((ttprty = parchk(dest,start,i)) > 0) {
- register int j;
- debug(F101,"ttinl senses parity","",ttprty);
- debug(F110,"ttinl packet before",dest,0);
- for (j = 0; j < i; j++)
- dest[j] &= 0x7f; /* Strip parity from packet */
- debug(F110,"ttinl packet after ",dest,0);
- } else debug(F101,"parchk","",ttprty);
- }
- #endif
- debug(F111,"ttinl got", dest,i);
- return(i);
- }
- } /* end while (i < max-1) */
- debug(F100,"ttinl timout","",0); /* Get here on timeout. */
- debug(F111," with",dest,i);
- return(x); /* and return error code. */
-
- } /* ttinl */
-
-
- /****************************************************************************/
- /* ttinc(timo) - read a character with timeout. Return -1 on timeout. */
- /****************************************************************************/
- ttinc (timo)
- int timo;
- {
- register int m, n = 0;
- long timeoticks;
- long intim; /* when we started */
-
- if (timo <= 0) { /* untimed */
- intim = 0; /* tell mac_myread not to timeout */
- timeoticks = 0;
- } else {
- timeoticks = timo * 60;
- intim = TickCount (); /* now */
- }
-
- m = (ttprty) ? 0177 : 0377; /* Parity stripping mask. */
-
- /* comm line failure returns -1 thru myread, so no &= 0377 */
- n = mac_myread(timeoticks,intim); /* Wait for a character... */
-
- /* debug(F101,"ttinc n","",n); */
- return(n < 0 ? n : n & m);
- } /* ttinc */
-
- /****************************************************************************/
- /* PWP: input as many chars as we can read from the serial line right now */
- /****************************************************************************/
-
- ttinm(buf, max)
- register char *buf;
- register int max;
- {
- long avil, num;
- int err, i;
-
- /*
- * DANGER WILL ROBINSON: this KNOWS about how mac_myread works
- * (in an insestious way), so BE CAREFUL!!!
- */
-
- if (my_count > 0) { /* do we have chars buffered up? */
- for (i = 0; (my_count > 0) && (i < max); i++)
- #ifdef notdef
- *buf++ = mac_mygetbuf(0L,0L);
- #else
- *buf++ = mac_myread(0L, 0L);
- #endif
- return (i); /* return contents of previous read buffer */
- }
-
- SerGetBuf (innum, &avil); /* Get available count */
-
- if (avil > 0) { /* Have something? */
- num = (avil > max) ? max : avil; /* Set max */
-
- err = FSRead (innum, &num, buf); /* Into our buffer */
- if (err != noErr)
- printerr ("Serial input error: ", err);
- return (num); /* return how many */
- } else {
- return (0);
- }
- }
-
- /****************************************************************************/
- /****************************************************************************/
- ttchk ()
- {
- long avcnt; /* pascal long */
-
- SerGetBuf (innum, &avcnt); /* get available */
-
- return (avcnt + my_count); /* return avail plus our own */
- } /* ttchk */
-
-
-
- /****************************************************************************/
- /* T T R E S -- Reset the serial line after doing a protocol things */
- /****************************************************************************/
- ttres ()
- {
- fInX = FALSE;
- return(sershake(flow));
- }
-
-
- unsigned long starttime;
- Boolean timerRunning = FALSE;
-
- /****************************************************************************/
- /* R T I M E R -- Reset elapsed time counter */
- /****************************************************************************/
- VOID rtimer ()
- {
- GetDateTime (&starttime);
- timerRunning = TRUE;
- } /* rtimer */
-
-
-
- /****************************************************************************/
- /* G T I M E R -- Get current value of elapsed time counter in seconds */
- /****************************************************************************/
- long
- gtimer ()
- {
- unsigned long secs;
-
- if (timerRunning) {
- GetDateTime (&secs);
- return (secs - starttime);
- timerRunning = FALSE;
- } else
- return (0);
- } /* gtimer */
-
-
- /****************************************************************************/
- /* Z T I M E -- Return date/time string */
- /****************************************************************************/
- VOID ztime (s)
- char **s;
- {
- #ifdef COMMENT
- /*
- This is no good. ztime() MUST return a string in asctime() format.
- */
- unsigned long secs;
- char timestr[10];
- static char dtime[25];
-
- GetDateTime (&secs);
- IUDateString (secs, shortDate, dtime);
- p2cstr(dtime);
- IUTimeString (secs, FALSE, timestr);
- p2cstr(timestr);
- strcat (dtime, " ");
- strcat (dtime, timestr);
- *s = dtime;
- #else
- #include <Time.h>
- time_t time(time_t *timer);
- char *ctime(const time_t *timer);
- time_t time_now;
- time_now = time( (time_t) 0 );
- *s = ctime( &time_now );
- #endif /* COMMENT */
- } /* ztime */
-
- /* Console IO routines. The console is implemented as a text edit structure.
- * These routines are supported:
- *
- * conoc(c) -- output one character to TE record at insertion point
- * conol(s) -- output null terminated string to TE record " "
- * conoll(s) -- same but with CR on the end
- * conxo(n,s) -- n character to TE record " "
- *
- */
-
- #define NILTE ((TEHandle ) NILPTR)
- #define LF 012
- #define CR 015
-
- /****************************************************************************/
- /* C O N X O -- Output string of length len to console text edit record */
- /****************************************************************************/
- conxo (len, s)
- int len;
- register char *s;
- {
- register char *t;
-
- /* change NLs to CRs for the Mac */
- for (t = s; *t && (t - s < len); t++)
- if (*t == LF)
- *t = CR;
-
- /* debug (F101, "conxo here: ", s, len); */
- if (rcmdw->teh == NULL)
- return(0);
-
- TEDeactivate(rcmdw->teh);
- trimcon(rcmdw, len);
- TEInsert (s, (long) len, rcmdw->teh); /* insert the string */
- TESetSelect(TE_MAX, TE_MAX, rcmdw->teh);
- TEActivate(rcmdw->teh);
- rcdwscroll (rcmdw); /* possibly scroll it */
-
- return (0);
- } /* conxo */
-
-
- /****************************************************************************/
- /* C O N O C -- Output a character to the console text edit record */
- /****************************************************************************/
- conoc (c)
- char c;
- {
- (void) conxo (1, &c);
- } /* conoc */
-
-
-
- /****************************************************************************/
- /****************************************************************************/
- conopen ()
- {
- return (1);
- } /* conopen */
-
-
-
- /****************************************************************************/
- /* C O N O L -- Write a line to the console text edit record */
- /****************************************************************************/
- conol (s)
- register char *s;
- {
- return (conxo (strlen (s), s));
- } /* conol */
-
-
-
-
- /****************************************************************************/
- /* C O N O L L -- Output a string followed by CRLF */
- /****************************************************************************/
- conoll (s)
- char *s;
- {
- (void) conol (s); /* first the string */
- (void) conoc (CR); /* now the return */
- return (0);
- } /* conoll */
-
-
- /*****************************************
- * C-Kermit Compatibility routines *
- *****************************************/
-
- /*
- * dummy routines for MAC
- */
- #define CINC(v,l)((v+1 == l)? 0 : v+1)
- #define CBL 25 /* console buffer length */
- int cbin = 0; /* circular buffer pointers */
- int cbout = 0;
- unsigned char cbuf[CBL]; /* console buffer */
-
- concb (esc)
- char esc;
- {
- }
-
- conres ()
- {
- }
-
- conchk ()
- {
- if (sstate == 'a') /* if cmd-. in miniparser */
- return 1;
- else
- return 0;
- }
-
- tthang ()
- {
- toggle_dtr(70);
- return(1);
- }
-
- VOID setint ()
- {
- }
-
- int pflag = 1;
-
- /*
- * ttgmdm
- * Get modem control signals.
- * The mac only has one input handshake (CTS) and one output
- * line (DTR). DTR may not be present on older MACS with
- * DB-9 (instead of DIN-8) connectors.
- */
- ttgmdm()
- {
- int err, r;
- SerStaRec stat;
-
- err = SerStatus(outnum, &stat);
- if (err != noErr) {
- printfalert("ttgmdm: Error getting serial status: %d", err);
- return -1; /* not available */
- }
- r = 0;
- if (!stat.ctsHold)
- r |= BM_CTS;
- /*
- * Always say dtr is on. We may be lying if we've enabled
- * dtr input flow control.
- */
- r |= BM_DTR;
-
- return r;
- }
-
-
- /*
- * Things from ckutio.c
- */
- int ckxech = 1; /* 0 if system normally echoes console characters, else 1 */
- char *ckxv = "Communications I/O, 5A(080), 14 Jan 92";
- int ttcarr = CAR_AUT; /* Carrier handling mode. */
-
- #include "ckuver.h" /* Version herald */
- char *ckxsys = HERALD;
-
- /* T T S C A R R -- Set ttcarr variable, controlling carrier handling.
- *
- * 0 = Off: Always ignore carrier. E.g. you can connect without carrier.
- * 1 = On: Heed carrier, except during dialing. Carrier loss gives disconnect.
- * 2 = Auto: For "modem direct": The same as "Off".
- * For real modem types: Heed carrier during connect, but ignore
- * it anytime else. Compatible with pre-5A C-Kermit versions.
- *
- * As you can see, this setting does not affect dialing, which always ignores
- * carrier (unless there is some special exception for some modem type). It
- * does affect ttopen() if it is set before ttopen() is used. This setting
- * takes effect on the next call to ttopen()/ttpkt()/ttvt(). And they are
- * (or should be) always called before any communications is tried, which
- * means that, practically speaking, the effect is immediate.
- *
- * Of course, nothing of this applies to remote mode (xlocal = 0).
- *
- * Someone has yet to uncover how to manipulate the carrier in the BSD
- * environment (or any non-termio using environment). Until that time, this
- * will simply be a no-op for BSD.
- *
- * Note that in previous versions, the carrier was most often left unchanged
- * in ttpkt()/ttvt() unless they were called with DIALING or CONNECT. This
- * has changed. Now it is controlled by ttcarr in conjunction with these
- * modes.
- */
- int ttscarr (carrier)
- int carrier;
- {
- ttcarr = carrier;
- debug(F101, "ttscarr","",ttcarr);
- return(ttcarr);
- }
-
-
- /*
- * from ckuusx.c
- */
- #ifdef DEBUG
- char debfil[50]; /* Debugging log file name */
- #endif /* DEBUG */
- char pktfil[50]; /* Packet log file name */
- #ifdef TLOG
- char trafil[50]; /* Transaction log file name */
- #endif /* TLOG */
- char sesfil[50]; /* Session log file name */
-
- #include "ckuusr.h"
- char fspec[FSPECL]; /* Filename string for \v(filespec) */
-
- VOID bgchk ()
- { /* Check background status */
- #ifdef notdef
- if (bgset < 0) pflag = !backgrd;
- else pflag = (bgset == 0 ? 1 : 0);
- #endif
- }
-
- /*
- * dbchr() for DEBUG SESSION
- */
- char *dbchr (c)
- int c;
- {
- static char s[8];
- char *cp = s;
-
- c &= 0xff;
- if (c & 0x80) { /* 8th bit on */
- sprintf(cp++,"~");
- c &= 0x7f;
- }
- if (c < SP) { /* Control character */
- sprintf(cp,"^%c",ctl(c));
- } else if (c == DEL) {
- sprintf(cp,"^?");
- } else { /* Printing character */
- sprintf(cp,"%c",c);
- }
- cp = s; /* Return pointer to it */
- return(cp);
- }
-
-
- /* T T X I N -- Get n characters from tty input buffer */
-
- /* Returns number of characters actually gotten, or -1 on failure */
-
- /* Intended for use only when it is known that n characters are actually */
- /* Available in the input buffer. */
-
- int ttxin (n,buf)
- int n;
- CHAR *buf;
- {
- int i, c;
-
- for (i = 0; i < n; i++) {
- c = ttinc(0);
- if (c < 0)
- return -1;
- *buf++ = ttinc(0); /* ignore errors */
- }
-
- return n;
- }
-
-
- /* C O N I N C -- Get a character from the console */
-
- int coninc (timo)
- int timo;
- {
- int c;
-
- newparser(1, 0, (long) timo); /* wait till timeout, no menus */
-
- if (cbin == cbout) /* if timeout */
- return -1;
-
- c = cbuf[cbout];
- cbout = CINC(cbout, CBL); /* advance pointer */
-
- return c;
- }
-
- char *ckxsys = " Apple Macintosh";
-
- /*
- * puts for mac console
- */
- puts (string)
- char *string;
- {
- int i;
-
- if (cmdinterminal)
- cursor_erase (ttermw);
-
- for (i = 0; i < strlen(string); i++)
- ucharout(string[i]);
-
- if (cmdinterminal) {
- if (ttermw->scroll_amount)
- flushscroll(ctermw); /* sync the screen */
- if (ctermw->out_maxcol) /* KLUDGE */
- flushbuf(ctermw);
- cursor_draw(ctermw);
- }
- }
-
-
- /*
- * printf for mac console
- */
- printf (char *format, ...)
- {
- int i;
- char string[512];
- va_list ap;
-
- va_start(ap, format);
- vsprintf(string, format, ap);
- va_end(ap);
-
- if (cmdinterminal)
- cursor_erase (ttermw);
-
- for (i = 0; i < strlen(string); i++)
- ucharout(string[i]);
-
- if (cmdinterminal) {
- if (ctermw->scroll_amount)
- flushscroll(ctermw); /* sync the screen */
- if (ctermw->out_maxcol) /* KLUDGE */
- flushbuf(ctermw);
- cursor_draw(ctermw);
- }
- }
-
-
- /*
- * putchar for mac console
- */
- putchar (c)
- char c;
- {
- if (cmdinterminal)
- cursor_erase (ttermw);
-
- ucharout(c);
-
- if (cmdinterminal) {
- if (ctermw->scroll_amount)
- flushscroll(ctermw); /* sync the screen */
- if (ctermw->out_maxcol) /* KLUDGE */
- flushbuf(ctermw);
- cursor_draw(ctermw);
- }
- }
-
-
- /*
- * outchar
- * output a character to a termw window.
- */
- void outchar (struct termw *termw, char c)
- {
- char buf[1];
-
- buf[0] = c;
-
- printem(termw, buf, 1);
- }
-
-
- /*
- * Send a single character to the console, unix format.
- * The MPW compiler thinks that '\r' is 0x0a and that
- * '\n' is 0x0d. In this routine, we translate things
- * to the appropriate action.
- *
- * This will be broken if we call this routine with chars
- * that are already correct, e.g.: CR.
- */
- ucharout (s)
- char s;
- {
- switch (s) {
- case '\n': /* unix newline -> CR, LF */
- cmdout(LF);
- cmdout(CR);
- return;
- case '\r': /* \r -> CR */
- cmdout(CR);
- return;
- default:
- cmdout(s);
- return;
- }
- }
-
-
- /*
- * cmdout
- * write a character to the command window
- * (copied from conxo)
- */
- VOID cmdout (c)
- char c;
- {
- char buf[1];
-
- buf[0] = c;
- /*
- * Output to terminal window if no command window.
- */
- if (cmdinterminal) {
- printem(ttermw, buf, 1);
- return;
- }
-
- printem(ctermw, buf, 1);
- }
-
-
- /*
- * getchar for mac console
- */
- getchar ()
- {
- int c;
-
- while (cbin == cbout) { /* while buffer is empty */
- if (sstate = newparser(1, 1, 0L)) {
- if (sstate == 'p') /* if wakeup flag */
- sstate = '\0';
- else if (sstate == 'n') { /* if null command state */
- sstate = '\0';
- return (-3);
- } else
- return(-3); /* NULL command */
- }
- }
-
- c = cbuf[cbout];
- cbout = CINC(cbout, CBL); /* advance pointer */
-
- return c;
- }
-
-
- /*
- * writecbc
- * Store a character into the console input buffer.
- */
- writecbc (c)
- char c;
- {
- int t;
-
- cbuf[cbin] = c;
- t = CINC(cbin, CBL); /* advance pointer */
- if (t == cbout) /* if buffer was full */
- return; /* drop character */
- cbin = t;
- }
-
-
- /*
- * writecb
- * Store a pascal string into the console input buffer.
- */
- writecb (string)
- char *string;
- {
- int l, i;
-
- l = *string++; /* length */
- for (i = 0; i < l; i++)
- writecbc(*string++);
- }
-
- /* C O N B I N -- Put console in binary mode */
-
- /* Returns 0 if ok, -1 if not */
-
- int
- #ifdef CK_ANSIC
- conbin (char esc)
- #else
- conbin (esc)
- char esc;
- #endif
- {
- return 0;
- }
-
- /*
- * Junk so Emacs will set local variables to be compatible with Mac/MPW.
- * Should be at end of file.
- * this module uses 8 char tabs
- *
- * Local Variables:
- * tab-width: 8
- * End:
- */
-